<?php

/**
 * Created by PhpStorm.
 * User: wenwb
 * Date: 2023/11/21
 * Time: 18:32
 */

namespace business\elasticsearch\services;

use business\elasticsearch\models\BigDataBidLifeCycleModel;

class BigDataBidLifeCycleService
{
    public function getList(
        $keyword,
        $searchType,
        $id,
        $subId,
        $areaCode,
        $type,
        $dataSourceCode,
        $publishDateStart,
        $publishDateEnd,
        $endDateStart,
        $endDateEnd,
        $companyAreaCode,
        $companyType,
        $companyLabel,
        $organizingCode,
        $page,
        $pageSize
    )
    {
        $condition = $this->constructConditionGetList(
            $keyword,
            $searchType,
            $id,
            $subId,
            $areaCode,
            $type,
            $dataSourceCode,
            $publishDateStart,
            $publishDateEnd,
            $endDateStart,
            $endDateEnd,
            $companyAreaCode,
            $companyType,
            $companyLabel,
            $organizingCode
        );
        if (empty($condition)) {
            return ['total' => 0, 'list' => []];
        }

        $query = BigDataBidLifeCycleModel::find()->query($condition);
        //高亮处理
        if (!empty($keyword)) {
            $highlight = [
                'pre_tags' => ['<em class="_high">'],
                'post_tags' => ['</em>'],
                "fields" => [
                    "title" => new \stdClass(),
                    "developer_name" => new \stdClass(),
                    "first_winbid_supplier_name" => new \stdClass(),
                    "second_winbid_supplier_name" => new \stdClass(),
                    "third_winbid_supplier_name" => new \stdClass(),
                ]
            ];
            $query->highlight($highlight);
        }

        $query->orderBy(["publish_date" => SORT_DESC, "id" => SORT_DESC]);
        $fieldes = ["id", "title", "type", "developer_name", "organizing_code", "company_type", "top_company_name", "top_company_organizing_code", "project_province"
            , "company_province", "company_province_code", "company_city", "company_city_code", "company_label_arr", "publish_date", "end_date", "data_source_code"
            , "first_winbid_supplier_name", "first_winbid_supplier_organizing_code", "second_winbid_supplier_name", "second_winbid_supplier_organizing_code", "third_winbid_supplier_name"
            , "third_winbid_supplier_organizing_code", "purchase_contact_cnt", "coop_supplier_contact_cnt"
            , "purchase_amount", "bidding_service_category", "link", "owner_contact_info" //本行的4个字段是导出招中表数据时会用到的字段
        ];
        $query->source($fieldes);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $searchData = $query->createCommand()->search();

        $total = 0;
        $list = [];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            $total = $searchData["hits"]["total"];
            foreach ($data as $dv) {
                $tmp = $dv['_source'];

                if (isset($dv['highlight']) && is_array($dv['highlight'])) {
                    foreach ($dv['highlight'] as $key => $value) {
                        $tmp[$key . 'HL'] = $value[0] ?? '';
                    }
                }
                $tmp['_score'] = $dv['_score'];

                //数据处理
                $tmp = $this->formatBid($tmp);

                $list[] = $tmp;
            }
        }
        return ['total' => $total, 'list' => $list];

    }

    public function formatBid($data)
    {
        $return_params = [
            'id' => 'string',
            'title' => 'string',
            'developer_name' => 'string',
            'organizing_code' => 'string',
            'company_type' => 'string',
            'top_company_name' => 'string',
            'top_company_organizing_code' => 'string',
            'project_province' => 'array',
            'company_province' => 'string',
            'company_province_code' => 'string',
            'company_city' => 'string',
            'company_city_code' => 'string',
            'company_label_arr' => 'array',
            'publish_date' => 'string',
            'end_date' => 'string',
            'data_source_code' => 'string',
            'first_winbid_supplier_name' => 'string',
            'first_winbid_supplier_organizing_code' => 'string',
            'first_winbid_supplier_contact_cnt' => 'int',
            'second_winbid_supplier_name' => 'string',
            'second_winbid_supplier_organizing_code' => 'string',
            'second_winbid_supplier_contact_cnt' => 'int',
            'third_winbid_supplier_name' => 'string',
            'third_winbid_supplier_organizing_code' => 'string',
            'third_winbid_supplier_contact_cnt' => 'int',
            'purchase_contact_cnt' => 'int',
            'coop_supplier_contact_cnt' => 'int',

            'titleHL' => 'string',
            'developer_nameHL' => 'string',
            'first_winbid_supplier_nameHL' => 'string',
            'second_winbid_supplier_nameHL' => 'string',
            'third_winbid_supplier_nameHL' => 'string',
            '_score' => 'int'
        ];

        $result = $data;
        foreach ($return_params as $rk => $rv) {
            $tmp = isset($data[$rk]) ? $data[$rk] : '';
            $tmp = $tmp === '1990-01-01 00:00:00' ? '' : $tmp;
            if ($rv == 'int') {
                $result[$rk] = (int)$tmp;
            } elseif ($rv == 'array') {
                $result[$rk] = empty($tmp) ? [] : $tmp;
            } else {
                $result[$rk] = $tmp;
            }
            //$result[$rk] = $rv == 'int' ? (int)$tmp : $tmp;
        }
        return $result;
    }

    public function constructConditionGetList(
        $keyword = '',
        $searchType = [],
        $id = '',
        $subId = '',
        $areaCode = [],
        $type = [],
        $dataSourceCode = [],
        $publishDateStart = '',
        $publishDateEnd = '',
        $endDateStart = '',
        $endDateEnd = '',
        $companyAreaCode = [],
        $companyType = [],
        $companyLabel = [],
        $organizingCode = []
    )
    {
        $must = [];

        //搜索
        if ($keyword != "") {
            $keywordCondition = [];
            //招标名称
            if (empty($searchType) || in_array('标题', $searchType)) {
                $keywordCondition[] = [
                    'match' => ['title.keyword' => ["query" => $keyword, "boost" => 100]]
                ];
                $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
                $keywordCondition[] = [
                    'match_phrase' => ['title' => ["query" => $keyword, "boost" => 0]]
                ];
            }

            //招标单位
            if (empty($searchType) || in_array('招标单位', $searchType)) {
                $keywordCondition[] = ['match_phrase' => ['developer_name' => ["query" => $keyword, "boost" => 0]]];
            }

            //中标单位
            if (empty($searchType) || in_array('中标单位', $searchType)) {
                //第一中标单位
                $keywordCondition[] = ['match_phrase' => ['first_winbid_supplier_name' => ["query" => $keyword, "boost" => 0]]];
                //第二中标单位
                $keywordCondition[] = ['match_phrase' => ['second_winbid_supplier_name' => ["query" => $keyword, "boost" => 0]]];
                //第三中标
                $keywordCondition[] = ['match_phrase' => ['third_winbid_supplier_name' => ["query" => $keyword, "boost" => 0]]];
            }

            $must[] = ["bool" => ["should" => $keywordCondition]];
        }

        if (!empty($areaCode)) {
            $must[] =
                ["nested" => ["path" => "project_province", "query" => [
                    "bool" => ["should" => [["terms" => ["project_province.city_code" => $areaCode]], ["terms" => ["project_province.province_code" => $areaCode]]]]
                ]]
                ];
        }

        if (!empty($companyAreaCode)) {
            $must[] = ["bool" => ["should" => [["terms" => ["company_city_code" => $companyAreaCode]], ["terms" => ["company_province_code" => $companyAreaCode]]]]];
        }

        if (!empty($companyLabel)) {
            $must[] = ["nested" => ["path" => "company_label_arr", "query" => ["terms" => ["company_label_arr.label" => $companyLabel]]]];
        }

        if (!empty($organizingCode)) {
            $must[] = ["terms" => ["organizing_code" => $organizingCode]];
        }

        if (!empty($id)) {
            $must[] = ["term" => ["id" => $id]];
        }
        if (!empty($subId)) {
            $must[] = ["term" => ["sub_id" => $subId]];
        }

        if (!empty($companyType)) {
            $must[] = ["terms" => ["company_type" => $companyType]];
        }

        if (!empty($type)) {
            $must[] = ["terms" => ["type" => $type]];
        }

        if (!empty($dataSourceCode)) {
            $must[] = ["terms" => ["data_source_code" => $dataSourceCode]];
        }


        //发布日期
        $publishDateRange = [];
        if (!empty($publishDateStart)) {
            $publishDateRange['gte'] = date('Y-m-d', strtotime($publishDateStart)) . " 00:00:00";
        }
        if (!empty($publishDateEnd)) {
            $publishDateRange['lt'] = date('Y-m-d', strtotime($publishDateEnd)) . " 23:59:59";
        }
        if (!empty($publishDateRange)) {
            $must[] = ['range' => ['publish_date' => $publishDateRange]];
        }

        //截止日期
        $endDateRange = [];
        if (!empty($endDateStart)) {
            $endDateRange['gte'] = date('Y-m-d', strtotime($endDateStart)) . " 00:00:00";
        }
        if (!empty($endDateEnd)) {
            $endDateRange['lt'] = date('Y-m-d', strtotime($endDateEnd)) . " 23:59:59";
        }
        if (!empty($endDateRange)) {
            $must[] = ['range' => ['end_date' => $endDateRange]];
        }


        $query['function_score']['query']['bool']['must'] = $must;
        //权重排序
        /*$query['function_score']['functions'] = [
            ['script_score' => ['script' => "doc['business_score'].value"]],
        ];*/
        $query['function_score']['score_mode'] = 'sum';
        $query['function_score']['boost_mode'] = 'sum';

        return $query;
    }


    public function guessName($keyword, $searchType, $pageSize): array
    {
        $condition = $this->constructConditionGetList($keyword, $searchType);
        $query = BigDataBidLifeCycleModel::find()
            ->query($condition);
        //高亮处理
        if (!empty($keyword)) {
            $highlight = [
                'pre_tags' => ['<em class="_high">'],
                'post_tags' => ['</em>'],
                "fields" => [
                    "title" => new \stdClass(),
                    "developer_name" => new \stdClass(),
                    "first_winbid_supplier_name" => new \stdClass(),
                    "second_winbid_supplier_name" => new \stdClass(),
                    "third_winbid_supplier_name" => new \stdClass(),
                ]
            ];
            $query->highlight($highlight);
        }
        $query->orderBy(['publish_date' => SORT_DESC, "id" => SORT_DESC]);

        //分页处理
        $query->limit($pageSize);
        $searchData = $query->createCommand()->search();
        //数据处理
        $result = [];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            foreach ($data as $dv) {
                $tmp = $dv['_source'];
                if (empty($keyword)) {
                    //非联想
                    $item["titleHL"] = '';
                    $item["title"] = $tmp['title'];
                    $result[] = $item;
                } else {
                    //联想
                    if (isset($dv['highlight']) && is_array($dv['highlight'])) {
                        foreach ($dv['highlight'] as $key => $value) {
                            $tmp[$key . 'HL'] = $value[0] ?? '';
                        }
                    }


                    $hl = '';
                    $title = '';
                    $item = [];
                    if (!empty($tmp['titleHL'])) {
                        $hl = $tmp['titleHL'];
                        $title = $tmp['title'];
                        $item['type'] = "title";
                    } else if (!empty($tmp['developer_nameHL'])) {
                        $hl = $tmp['developer_nameHL'];
                        $title = $tmp['developer_name'];
                        $item['type'] = "developer_name";
                    } else if (!empty($tmp['first_winbid_supplier_nameHL'])) {
                        $hl = $tmp['first_winbid_supplier_nameHL'];
                        $title = $tmp['first_winbid_supplier_name'];
                        $item['type'] = "winbid_supplier";
                    } else if (!empty($tmp['second_winbid_supplier_nameHL'])) {
                        $hl = $tmp['second_winbid_supplier_nameHL'];
                        $title = $tmp['second_winbid_supplier_name'];
                        $item['type'] = "winbid_supplier";
                    } else if (!empty($tmp['third_winbid_supplier_nameHL'])) {
                        $hl = $tmp['third_winbid_supplier_nameHL'];
                        $title = $tmp['third_winbid_supplier_name'];
                        $item['type'] = "winbid_supplier";
                    }


                    $item["titleHL"] = $hl;
                    $item["title"] = $title;
                    $result[] = $item;
                }

            }
        }
        return $result;
    }
}
